package com.rayc.mall.user.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rayc.mall.api.dto.LoginFormDTO;
import com.rayc.mall.api.dto.RegisterFormDTO;
import com.rayc.mall.api.dto.UserUpdateDTO;
import com.rayc.mall.common.context.UserContext;
import com.rayc.mall.common.enums.UserStatus;
import com.rayc.mall.common.exception.BadRequestException;
import com.rayc.mall.common.exception.BizIllegalException;
import com.rayc.mall.core.properties.AdminProperties;
import com.rayc.mall.common.utils.CollUtils;
import com.rayc.mall.common.utils.JwtTool;
import com.rayc.mall.user.domain.po.User;
import com.rayc.mall.user.domain.query.UserPageQuery;
import com.rayc.mall.user.domain.vo.UserLoginVO;
import com.rayc.mall.user.mapper.UserMapper;
import com.rayc.mall.user.service.IUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @Author: Ray-C
 * @CreateTime: 2025-03-25
 * @Description: 用户service实现
 * @Version: 1.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    private final JwtTool jwtTool;
    private final AdminProperties adminProperties;

    @Override
    public UserLoginVO login(LoginFormDTO loginDTO) {
        String username = loginDTO.getUsername();
        String password = loginDTO.getPassword();
        User user = lambdaQuery().eq(User::getUsername, username).one();
        // 校验用户是否存在
        if (user == null) {
            throw new BadRequestException("用户名错误");
        }
        // 校验是否禁用
        if (user.getStatus() == UserStatus.FROZEN) {
            throw new BizIllegalException("用户已注销");
        }
        // 校验密码
        if (!user.getPassword().equals(password)) {
            throw new BadRequestException("用户名或密码错误");
        }
        // 生成TOKEN
        String token = jwtTool.createToken(user.getId());
        // 封装VO返回
        UserLoginVO vo = new UserLoginVO();
        vo.setUserId(user.getId());
        vo.setUsername(user.getUsername());
        vo.setBalance(user.getBalance());
        vo.setToken(token);
        // 设置是否管理员
        List<Long> admins = adminProperties.getAdmins();
        vo.setIsAdmin(CollUtils.isNotEmpty(admins) && admins.contains(user.getId()));
        return vo;
    }

    @Override
    // 该方法会被feign调用，且调用时位于事务中，需要补充事务注解
    @Transactional(rollbackFor = Exception.class)
    public void deductMoney(String pw, Integer totalFee) {
        // 校验密码
        User user = getById(UserContext.getUser());
        if (user == null || !user.getPassword().equals(pw)) {
            throw new BizIllegalException("用户密码错误");
        }
        // 查看余额是否足够
        Integer balance = user.getBalance();
        if (balance == null || balance < totalFee) {
            throw new BizIllegalException("扣款失败，余额不足");
        }
        baseMapper.updateMoney(UserContext.getUser(), totalFee);
    }

    @Override
    public void register(RegisterFormDTO registerFormDTO) {
        User dbUser = lambdaQuery().eq(User::getUsername, registerFormDTO.getUsername()).one();
        if (dbUser != null) {
            throw new BizIllegalException("用户已存在");
        }
        User user = new User();
        user.setUsername(registerFormDTO.getUsername());
        user.setPhone(registerFormDTO.getPhone());
        // 密码使用md5加密
        String md5Password = DigestUtil.md5Hex(registerFormDTO.getPassword());
        user.setPassword(md5Password);
        user.setStatus(UserStatus.NORMAL);
        user.setBalance(0);
        LocalDateTime now = LocalDateTime.now();
        user.setCreateTime(now);
        user.setUpdateTime(now);
        save(user);
    }

    @Override
    public void updateInfo(UserUpdateDTO userUpdateDTO) {
        User user = getById(UserContext.getUser());
        if (user == null) {
            throw new BizIllegalException("用户不存在");
        }
        if (userUpdateDTO.getPhone() != null) {
            user.setPhone(userUpdateDTO.getPhone());
        }
        if (userUpdateDTO.getRechargeBalance() != null) {
            // 充值余额
            user.setBalance(user.getBalance() + userUpdateDTO.getRechargeBalance());
        }
        if (userUpdateDTO.getIsDeleted() != null && userUpdateDTO.getIsDeleted()) {
            // 注销账号
            user.setStatus(UserStatus.FROZEN);
        } else if (!user.getPassword().equals(userUpdateDTO.getPassword())) {
            // 注销账号不需要验证密码
            throw new BizIllegalException("密码错误");
        }
        user.setUpdateTime(LocalDateTime.now());
        updateById(user);
    }

    @Override
    public Page<User> search(UserPageQuery query) {
        return lambdaQuery()
                .eq(query.getId() != null, User::getId, query.getId())
                .like(StrUtil.isNotBlank(query.getUsername()), User::getUsername, query.getUsername())
                .page(query.toMpPage("create_time", false));
    }
}
